package cn.dingd.simplenes;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class GamePadLeft extends View {

    private Context context;
    private int OUTER_WIDTH_SIZE;
    private int OUTER_HEIGHT_SIZE;
    private Paint outerPaint;
    private int outerRadius;
    private Paint innerPaint;
    private int innerCenterX;
    private int innerCenterY;
    private int innerRadius;
    private double radian;
    private double distance;
    private OnTouchListener onTouchListener;

    public void setOnTouchListener(OnTouchListener onTouchListener) {
        this.onTouchListener = onTouchListener;
    }

    static interface OnTouchListener {
        void onTouch(double d, double r);
    }

    public GamePadLeft(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        OUTER_WIDTH_SIZE = dip2px(context, 125.0f);
        OUTER_HEIGHT_SIZE = dip2px(context, 125.0f);
        outerPaint = new Paint();
        innerPaint = new Paint();
        outerPaint.setAntiAlias(true);
        innerPaint.setAntiAlias(true);
        outerPaint.setColor(Color.parseColor("#f44336"));
        innerPaint.setColor(Color.parseColor("#d32f2f"));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);

        innerCenterX = width / 2;
        innerCenterY = width / 2;
        innerRadius = dip2px(context, 25);
        outerRadius = width / 2;

        setMeasuredDimension(width, height);
    }

    private int measureWidth(int widthMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);
        //处理三种模式
        if (widthMode == MeasureSpec.EXACTLY) {
            return widthVal + getPaddingLeft() + getPaddingRight();
        } else if (widthMode == MeasureSpec.UNSPECIFIED) {
            return OUTER_WIDTH_SIZE;
        } else {
            return Math.min(OUTER_WIDTH_SIZE, widthVal);
        }


    }

    private int measureHeight(int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightVal = MeasureSpec.getSize(heightMeasureSpec);
        //处理三种模式
        if (heightMode == MeasureSpec.EXACTLY) {
            return heightVal + getPaddingTop() + getPaddingBottom();
        } else if (heightMode == MeasureSpec.UNSPECIFIED) {
            return OUTER_HEIGHT_SIZE;
        } else {
            return Math.min(OUTER_HEIGHT_SIZE, heightVal);
        }
    }

//    @Override
//    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//        super.onSizeChanged(w, h, oldw, oldh);
//        realWidth = w;
//        realHeight = h;
//        innerCenterX = realWidth/2;
//        innerCenterY = realHeight/2;
//    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int cx = getMeasuredWidth() / 2;
        int cy = getMeasuredWidth() / 2;
        //画外部圆
        canvas.drawCircle(cx, cy, outerRadius, outerPaint);
        //内部圆
        // innerRedius = outRadius*0.5f;
        canvas.drawCircle(innerCenterX, innerCenterY, innerRadius, innerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            changeInnerCirclePosition(event);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            changeInnerCirclePosition(event);
            // Log.i("TAG", "MOVED");
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            innerCenterX = getMeasuredWidth() / 2;
            innerCenterY = getMeasuredHeight() / 2;
            radian = 0;
            distance = 0;
            invalidate();
        }
        if (onTouchListener != null)
            onTouchListener.onTouch(distance, radian);
        return true;
    }


    private void changeInnerCirclePosition(MotionEvent e) {
        float pointX = e.getX();
        float pointY = e.getY();

        int relX = (int) (pointX - outerRadius);
        int relY = (int) -(pointY - outerRadius);

        int va = Math.abs(relX);
        int vb = Math.abs(relY);

        if (Math.pow(relX, 2)
                + Math.pow(relY, 2)
                > Math.pow(outerRadius - innerRadius, 2)
        ) {

//            double sina = (double) vb / Math.sqrt(Math.pow(va, 2) + Math.pow(vb, 2));
//
//            double newY = (outerRadius - innerRadius) * sina;
//            double newX = Math.sqrt((Math.pow(outerRadius - innerRadius, 2) - Math.pow(newY, 2)));
//
//            if(relX < 0)
//                newX = -newX;
//            if(relY < 0)
//                newY = -newY;
//
//            innerCenterX = (int) (outerRadius+newX);
//            innerCenterY = (int) (outerRadius+newY);
            radian = Math.atan2(relY, relX);
            if (radian < 0) {
                radian = 2 * Math.PI + radian;
            }

            double sina = Math.sin(radian);

            //Log.d("sina", "" + sina);

            double newY = (outerRadius - innerRadius) * sina;

            double newX = Math.sqrt((Math.pow(outerRadius - innerRadius, 2) - Math.pow(newY, 2)));

            if (relX < 0)
                newX = -newX;
            //if (relY < 0)
            //    newY = -newY;
            distance = outerRadius - innerRadius;
            innerCenterX = (int) (outerRadius + newX);
            innerCenterY = (int) (outerRadius - newY);
        } else {
            distance = Math.sqrt(Math.pow(relX, 2)
                    + Math.pow(relY, 2));

            radian = Math.atan2(relY, relX);

            innerCenterX = (int) pointX;
            innerCenterY = (int) pointY;
        }
        invalidate();

    }

    //    public void setOnNavAndSpeedListener(OnNavAndSpeedListener listener){
//        mCallBack = listener;
//    }
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
